
# menus.pl -- Copyright (c) 1990, Henk P. Penning.
# You may distribute under the terms of the GNU General Public License
# as specified in the README file that comes with the Jinx 2.1 kit.

sub addMenu
  { local(*Menu,$entry,$choice,$tag,$help) = @_ ;
    push(@Menu,$entry) ;
    if ( $entry !~ /arrow=/ )
      { $Menu{$choice} = $tag ;
        $Menu{"help_$choice"} = $help ;
	if ( $entry =~ /TAB=/ )
          { $Menu{'KEY_TAB'} = $choice ;
            $Menu{"help_KEY_TAB"} = $help ;
	  }
      }
    else
      { if ( $entry =~ /^arrow=/ )
          { $Menu{'KEY_LEFT'}       = 'left' ;
            $Menu{'KEY_DOWN'}       = 'down' ;
            $Menu{'KEY_UP'}         = 'up' ;
	    $Menu{'KEY_RIGHT'}      = 'right' ;
            $Menu{'help_KEY_LEFT'}  = 'move view left' ;
            $Menu{'help_KEY_DOWN'}  = 'move cursor down' ;
            $Menu{'help_KEY_UP'}    = 'move cursor up' ;
            $Menu{'help_KEY_RIGHT'} = 'move view right' ;
          }
        if ( $entry =~ /left.*arrow=/ )
          { $Menu{'KEY_LEFT'}       = 'left' ;
            $Menu{"help_KEY_LEFT"}  = $choice ;
	  }
        if ( $entry =~ /down.*arrow=/ )
          { $Menu{'KEY_DOWN'}       = 'down' ;
            $Menu{"help_KEY_DOWN"}  = $choice ;
	  }
        if ( $entry =~ /up.*arrow=/ )
          { $Menu{'KEY_UP'}         = 'up' ;
            $Menu{"help_KEY_UP"}    = $choice ;
	  }
        if ( $entry =~ /right.*arrow=/ )
          { $Menu{'KEY_RIGHT'}      = 'right' ;
            $Menu{"help_KEY_RIGHT"} = $choice ;
	  }
      }
  }

sub makeMenu
  { local(*Menu) = @_ ;
    local($cnt,$curlen) = (-1,$maxMenuWidth) ;
    local(@res,$entry,$i,$strlen,$_) ;

    if ( defined $Menu{'SAVE_SIZE'} )
      { $#Menu += $Menu{'SAVE_SIZE'} ;
        splice(@Menu,0,$#Menu-$Menu{'SAVE_SIZE'}+1) ;
      }

    for $entry ( @Menu )
      { $_ = ( $i == $#Menu ) ? "or $entry" : "$entry," ;
	$strlen = length ;
	if ( $strlen > $maxMenuWidth )
	  { &addlog("maxMenuWidth $maxMenuWidth") unless $menuError ;
	    &addlog("Too wide: $_") ;
	    $menuError = 1 ;
	  }
        if ( $curlen + $strlen >= $maxMenuWidth )
          { $cnt++ ;
            push(@res,$_) ;
            $curlen = $strlen ;
          }
        else
          { $curlen += ($strlen+1) ;
            $res[$cnt] .= ( ' ' . $_ ) ;
          }
	$i++ ;
      }
    $Menu{'SAVE_SIZE'} = $#Menu+1 ;
    unshift(@Menu,@res) ;
    $#Menu = $#res ;
    return $#Menu ;
  }

%metaMenu = () ;
@metaMenu = () ;
&addMenu(*metaMenu,"arrow=scroll") ;
&addMenu(*metaMenu,"n)ext",'n','next','show next data page') ;
&addMenu(*metaMenu,"p)rev",'p','prev','show previous data page') ;
&addMenu(*metaMenu,"g)oto",'g','goto','ask record number; show record') ;
&addMenu(*metaMenu,"/=search",'/','search','ask regexp; show matching record') ;
&addMenu(*metaMenu,";=re-search",';','re-search',
  'search with previous regexp; show matching record') ;
&addMenu(*metaMenu,"i)nspect",'i','inspect','show data record by record') ;
&addMenu(*metaMenu,"D)escr",'D','Descr','inspect and change descriptor') ;
&addMenu(*metaMenu,"P)roject",'P','Project','select columns by name') ;
&addMenu(*metaMenu,"J)oin",'J','Join','join database on cols with same name') ;
&addMenu(*metaMenu,"O)rder",'O','Order','sort on specific keys' ) ;
&addMenu(*metaMenu,"T)est all",'T','Test','test if records match the cpats') ;
&addMenu(*metaMenu,"A)dd field",'A','Add field','add a field to the database') ;
&addMenu(*metaMenu,"s)ave",'s','save','save current database') ;
&addMenu(*metaMenu,"S)ave as",'S','Save as','save db under specific name') ;
&addMenu(*metaMenu,"o)pen",'o','open','open a new database') ;
&addMenu(*metaMenu,"G)uess",'G','Guess','ask file and separator, build db') ;
&addMenu(*metaMenu,"C)lear",'C','Clear','Forget about current database') ;
&addMenu(*metaMenu,"V)iew toggle",'V','View','Toggles view in collumns') ;
&addMenu(*metaMenu,"TAB=q)uit",'q','quit','leave jinx') ;
&addMenu(*metaMenu,"Q)uit without save",'Q','QUIT','leave jinx; no update') ;

%mainMenu = () ;
@mainMenu = () ;
&addMenu(*mainMenu,'arrow=scroll') ;
&addMenu(*mainMenu,"n)ext",'n','next','show next record') ;
&addMenu(*mainMenu,"p)rev",'p','previous','show previous record') ;
&addMenu(*mainMenu,"g)oto",'g','goto','ask number; show record') ;
&addMenu(*mainMenu,"/=search",'/','search','ask pattern; search record') ;
&addMenu(*mainMenu,";=re-search",';','re-search',
  'search with previous regexp; show matching record') ;
&addMenu(*mainMenu,"u)pdate",'u','update','edit current record') ;
&addMenu(*mainMenu,"a)dd",'a','add','add empty record; edit') ;
&addMenu(*mainMenu,"c)opy",'c','copy','copy current record; edit') ;
&addMenu(*mainMenu,"d)elete",'d','delete','delete current record') ;
&addMenu(*mainMenu,"U)ndo",'U','Undo','put back deleted records') ;
&addMenu(*mainMenu,"C)ompute",'C','Compute',
  'compute new values for one or more columns') ;
&addMenu(*mainMenu,"E)xtract",'E','Extract','Extract selection') ;
&addMenu(*mainMenu,"D)elete",'D','Delete','Delete selection') ;
&addMenu(*mainMenu,"P)eek",'P','Peek',
  'ask for database; present records to select') ;
&addMenu(*mainMenu,"R)ead",'R','Read',
  'ask for database; present only new records to select') ;
&addMenu(*mainMenu,"K)ey test",'K','Key test',
  'ask key-fields; test if keys are unique (if no keys, uniq records)') ;
&addMenu(*mainMenu,"O)rder",'O','Order','sort on specific keys' ) ;
&addMenu(*mainMenu,"t)est",'t','test','test if fields match cpats') ;
&addMenu(*mainMenu,"T)est all",'T','Test','test if all records match cpats') ;
&addMenu(*mainMenu,"TAB=f)inish",'f','finish','leave inspect mode') ;
&addMenu(*mainMenu,"Q)uit without save",'Q','QUIT','leave jinx; no update') ;

%selectFromMenu = () ;
@selectFromMenu = () ;
&addMenu(*selectFromMenu,"arrow=scroll") ;
&addMenu(*selectFromMenu,"n)ext",'n','next','show next record') ;
&addMenu(*selectFromMenu,"p)rev",'p','previous','show previous record') ;
&addMenu(*selectFromMenu,"g)oto",'g','goto','ask number; show record') ;
&addMenu(*selectFromMenu,"/=search",'/','search','ask pattern; search record') ;
&addMenu(*selectFromMenu,";=re-search",';','re-search',
  'search with previous regexp; show matching record') ;
&addMenu(*selectFromMenu,">=next mark",'>','next mark',
  'goto next marked record') ;
&addMenu(*selectFromMenu,"<=prev mark",'<','previous mark',
  'goto previous marked record') ;
&addMenu(*selectFromMenu,")=next unmark",')','next unmark',
  'goto next unmarked record') ;
&addMenu(*selectFromMenu,"(=prev unmark",'(','previous unmark',
  'goto previous unmarked record') ;
&addMenu(*selectFromMenu,"t)oggle",'t','toggle','toggle marking') ;
&addMenu(*selectFromMenu,"T)oggle",'T','Toggle all',
  'toggle marking of all records') ;
&addMenu(*selectFromMenu,"C)lear",'C','Clear marks',
  'unmark all records') ;
&addMenu(*selectFromMenu,"M)ark",'M','Mark subset','ask patterns; mark') ;
&addMenu(*selectFromMenu,"U)nmark",'U','Unmark subset','ask patterns; unmark') ;
&addMenu(*selectFromMenu,"s)elect one",'s','select',
  'select only the current record') ;
&addMenu(*selectFromMenu,"S)elect marked",'S','select marked',
  'select all marked records') ;
&addMenu(*selectFromMenu,"TAB=ex)it select",'x','exit',
  'back to previous menu; no changes; no selection') ;

@updateMenu= () ;
%updateMenu= () ;
&addMenu(*updateMenu,"arrow=move cursor") ;
&addMenu(*updateMenu,"TAB=finish",'','','finish update') ;

@updateXMenu= () ;
%updateXMenu= () ;
&addMenu(*updateXMenu,"a)ccept",'a','accept','confirm this update') ;
&addMenu(*updateXMenu,"TAB=f)orget",'f','forget','leave it as it was') ;
&addMenu(*updateXMenu,"e)dit",'e','edit','edit it again') ;

@updMatchMenu= () ;
%updMatchMenu= () ;
&addMenu(*updMatchMenu,"e)dit",'e','edit','edit it again') ;
&addMenu(*updMatchMenu,"a)ccept",'a','accept','confirm this update') ;
&addMenu(*updMatchMenu,"f)orget",'f','forget','leave it as it was') ;
&addMenu(*updMatchMenu,"TAB=ex)it",'x','exit','abandon all changes') ;

@updReMenu= () ;
%updReMenu= () ;
&addMenu(*updReMenu,"e)dit",'e','edit','edit it again') ;
&addMenu(*updReMenu,"f)orget",'f','forget','leave it as it was') ;
&addMenu(*updReMenu,"TAB=ex)it",'x','exit','abandon all changes') ;

@dirtyMenu= () ;
%dirtyMenu= () ;
&addMenu(*dirtyMenu,"y)es",'y','yes','confirm') ;
&addMenu(*dirtyMenu,"TAB=n)o",'n','no','deny') ;

@noKeyMenu= () ;
%noKeyMenu= () ;
&addMenu(*noKeyMenu,"a)dd empty data",'a','add',
  'add empty join-data for this record') ;
&addMenu(*noKeyMenu,"d)elete this record",'d','delete',
  'don\'t join with this record') ;
&addMenu(*noKeyMenu,"A)dd empty data for all undefined keys",'A','Add',
  'add empty join-data for all records that don\'t join with anything') ;
&addMenu(*noKeyMenu,"D)elete all undefined keys",'D','Delete',
  'don\'t join with any record that can\'t be joined with properly') ;
&addMenu(*noKeyMenu,"TAB=ex)it",'x','exit','leave Join; no change') ;

@multiKeyMenu= () ;
%multiKeyMenu= () ;
&addMenu(*multiKeyMenu,"a)dd all",'a','add',
  'join with all records') ;
&addMenu(*multiKeyMenu,"A)lways add all",'A','Always add all',
  'always join with all possible records') ;
&addMenu(*multiKeyMenu,"d)elete this record",'d','delete',
  'leave this record out of the join') ;
&addMenu(*multiKeyMenu,"D)elete Multi's always",'D','Delete',
  'leave out any record which can be joined with more than one record') ;
&addMenu(*multiKeyMenu,"s)how to select",'s','show',
  'show which records can be joined with') ;
&addMenu(*multiKeyMenu,"TAB=ex)it",'x','exit','leave Join; no change') ;

@keyTestMenu= () ;
%keyTestMenu= () ;
&addMenu(*keyTestMenu,"n)ext",'n','next',
  'skip current record; test following records') ;
&addMenu(*keyTestMenu,"s)how to delete",'s','show',
  'show records; delete selection') ;
&addMenu(*keyTestMenu,"f)inish",'f','finish',
  'leave Keytest; make changes indicated sofar') ;
&addMenu(*keyTestMenu,"TAB=ex)it",'x','exit','leave Keytest; no change') ;

@searchMenu= () ;
%searchMenu= () ;
&addMenu(*searchMenu,"up/down-arrow=previous entries",
  'scroll through previous entries') ;
&addMenu(*searchMenu,"RET=finish",'','') ;
&addMenu(*searchMenu,"TAB=exit",'','') ;

@testMenu= () ;
%testMenu= () ;
&addMenu(*testMenu,"n)ext",'n','next','search next mismatch') ;
&addMenu(*testMenu,"N)ext",'N','Next','search next record with mismatch') ;
&addMenu(*testMenu,"u)pdate",'u','update','update current record') ;
&addMenu(*testMenu,"TAB=ex)it",'x','exit','leave testing') ;

@getNamesMenu= () ;
%getNamesMenu= () ;
&addMenu(*getNamesMenu,"up/down-arrow=move cursor",'move cursor') ;
&addMenu(*getNamesMenu,"right-arrow=select",'select/de-select') ;
$getNamesMenu{'KEY_RIGHT'} = 'select' ;
$getNamesMenu{'help_KEY_RIGHT'} = 'select current name' ;
$getNamesMenu{'l'} = 'select' ;
$getNamesMenu{'help_l'} = 'select current name' ;
&addMenu(*getNamesMenu,"left-arrow=delete") ;
$getNamesMenu{'KEY_LEFT'} = 'delete' ;
$getNamesMenu{'help_KEY_LEFT'} = 'de-select current name' ;
$getNamesMenu{'h'} = 'delete' ;
$getNamesMenu{'help_h'} = 'de-select current name' ;
&addMenu(*getNamesMenu,"i)ncr",'i','increment',
  'move current name up in the list') ;
&addMenu(*getNamesMenu,"d)ecr",'d','decrement',
  'move current name down in the list') ;
&addMenu(*getNamesMenu,"s)how",'s','show',
  'show the current list by name') ;
&addMenu(*getNamesMenu,"f)inish",'f','finish',
  'leave select mode') ;
&addMenu(*getNamesMenu,"TAB=ex)it",'x','exit',
  'abandon select; no change') ;

@doDescrMenu= () ;
%doDescrMenu= () ;
&addMenu(*doDescrMenu,"up/down-arrow=move cursor",'move cursor') ;
&addMenu(*doDescrMenu,"p)at edit",'p','pat edit','edit patterns') ;
&addMenu(*doDescrMenu,"n)ame edit",'n','name edit','update names') ;
&addMenu(*doDescrMenu,"f)inish",'f','finish','finish updating') ;
&addMenu(*doDescrMenu,"TAB=ex)it",'x','exit','leave; no updates') ;

sub initMenus {
  local($maxMenuWidth) = @_ ;
  $maxMenuSize = &max(
    &makeMenu(*metaMenu),
    &makeMenu(*mainMenu),
    &makeMenu(*updateMenu),
    &makeMenu(*updateXMenu),
    &makeMenu(*updReMenu),
    &makeMenu(*updMatchMenu),
    &makeMenu(*searchMenu),
    &makeMenu(*dirtyMenu),
    &makeMenu(*noKeyMenu),
    &makeMenu(*multiKeyMenu),
    &makeMenu(*keyTestMenu),
    &makeMenu(*selectFromMenu),
    &makeMenu(*testMenu),
    &makeMenu(*getNamesMenu),
    &makeMenu(*doDescrMenu)
  ) ;

  &QUIT('terminal not wide enough for menu.') if $menuError ;
}

1;
